﻿using System;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using QTMusic.BaseClasses;
using QTMusic.UserControls;

namespace QTMusic.Websites
{
    public partial class Profile : System.Web.UI.Page
    {
        private int[] friendIDs = new int[10];
        private int cookieId = 0;
        private int userId = 0;

        public void cmdDeny_Click(object sender, EventArgs e)
        {
            string updateSql = "UPDATE [friendreq] SET "
                                + "friendreq_status = @status "
                                + "WHERE friendreq_from_id = @fromId "
                                + "AND user_id = @userId";
            SqlConnection conn = new SqlConnection(Common.connString);
            SqlCommand cmd = new SqlCommand(updateSql, conn);
            cmd.Parameters.AddWithValue("@status", "Denied");
            cmd.Parameters.AddWithValue("@fromId", userId);
            cmd.Parameters.AddWithValue("@userId", cookieId);

            int updated = 0;
            try
            {
                using (conn)
                {
                    conn.Open();
                    updated = cmd.ExecuteNonQuery();
                }
            }
            catch (Exception requestListEx)
            {
                //RequestListItemException newException =
                //            new RequestListItemException(requestListEx.Message, requestListEx);
                //throw newException;
                Common.WriteToEventLog(requestListEx, "DenyRequest");
            }

            if (updated > 0)
            {
                pnlFriendButtons.Controls.Clear();
                LiteralControl objReport = new LiteralControl("Yêu cầu đã bị từ chối.");
                pnlFriendButtons.Controls.Add(objReport);
            }
        }

        public void cmdAccept_Click(object sender, EventArgs e)
        {
            string updateSql = "UPDATE [friendreq] SET "
                                + "friendreq_status = @status "
                                + "WHERE friendreq_from_id = @fromId "
                                + "AND user_id = @userId";
            SqlConnection conn = new SqlConnection(Common.connString);
            SqlCommand cmd = new SqlCommand(updateSql, conn);
            cmd.Parameters.AddWithValue("@status", "Accepted");
            cmd.Parameters.AddWithValue("@fromId", userId);
            cmd.Parameters.AddWithValue("@userId", cookieId);

            int updated = 0;
            try
            {
                conn.Open();
                updated = cmd.ExecuteNonQuery();
            }
            catch (Exception requestListEx)
            {
                //RequestListItemException newException =
                //            new RequestListItemException(requestListEx.Message, requestListEx);
                //throw newException;
                Common.WriteToEventLog(requestListEx, "AcceptRequest");
            }

            conn.Close();

            if (updated > 0)
            {
                string insertSql = "INSERT INTO [friend] VALUES (@userId, @friendId)";
                cmd = new SqlCommand(insertSql, conn);
                cmd.Parameters.AddWithValue("@userId", userId);
                cmd.Parameters.AddWithValue("@friendId", cookieId);

                conn.Open();
                cmd.ExecuteNonQuery();
                conn.Close();

                cmd = new SqlCommand(insertSql, conn);
                cmd.Parameters.AddWithValue("@userId", cookieId);
                cmd.Parameters.AddWithValue("@friendId", userId);

                conn.Open();
                cmd.ExecuteNonQuery();
                conn.Close();

                pnlFriendButtons.Controls.Clear();
                LiteralControl objReport = new LiteralControl("Yêu cầu đã được chấp nhận.");
                pnlFriendButtons.Controls.Add(objReport);
                // TODO: chọn nhóm
            }
        }

        protected void Page_Load(object sender, EventArgs e)
        {
            cmdRequestFriend.Visible = false;
            cmdAccept.Visible = false;
            cmdDeny.Visible = false;
            // logged in or not?
            HttpCookie cookie = Request.Cookies["QTCookie"];
            if (cookie == null)
            {
                Response.Redirect("Login.aspx");
            }

            cookieId = Int32.Parse(cookie["ID"]);
            // with query string
            if (Int32.TryParse(Request.QueryString["id"], out userId) && userId != 0)
            {
                // display profile name
                LiteralControl objPanelName = new LiteralControl(Common.GetUserName(userId));
                pnlUserName.Controls.Add(objPanelName);
                // display profile image
                imgProfile.ImageUrl = Common.GetUserImgUrl(userId);
                
                // the surfer is the owner
                if (userId == cookieId)
                {
                    //if there is a request to share a song, view the sharing panel
                    if (Request.QueryString["SongId"] != null)
                    {
                        Control sharingPanel = LoadControl("../UserControls/ShareASong.ascx");
                        pnlShareASong.Controls.Add(sharingPanel);
                    }
                    else
                    {
                        //else show an upload button
                        Button goUploadPage = new Button();
                        goUploadPage.Text = "Upload";
                        goUploadPage.CssClass = "button_modded2";
                        goUploadPage.Width = Unit.Pixel(110);
                        goUploadPage.Height = Unit.Pixel(41);
                        goUploadPage.Click += new EventHandler(BtnUploadClicked);

                        Panel PnlButtonHolder = new Panel();
                        PnlButtonHolder.CssClass = "main_content_profile_uploadbutton";
                        PnlButtonHolder.Controls.Add(goUploadPage);
                        pnlShareASong.Controls.Add(PnlButtonHolder);
                    }

                    lnkProfileImage.NavigateUrl = "ProfileEdit.aspx?w=image";
                    GetFriendList(userId);
                    GetPostList(userId, Common.Permission.Private);
                    GetRequestList(userId);
                }
                // the surfer is a friend of the owner
                else if (Common.IsFriend(userId, cookieId))
                {
                    lnkProfileImage.NavigateUrl = Request.RawUrl;
                    GetFriendList(userId);
                    GetPostList(userId, Common.Permission.Friend);
                }
                // the surfer is neither the owner nor his/her friend
                else
                {
                    lnkProfileImage.NavigateUrl = Request.RawUrl;

                    // is request sent from the surfer to the owner?
                    int ret = Common.IsRequestSent(cookieId, userId);
                    // not yet
                    if (ret == 0)
                    {
                        cmdRequestFriend.Text = "Kết bạn";
                        cmdRequestFriend.Visible = true;
                        cmdRequestFriend.Enabled = true;
                    }
                    // sent, waiting for response
                    else if (ret == 1)
                    {
                        cmdRequestFriend.Text = "Đã gửi đề nghị";
                        cmdRequestFriend.Visible = true;
                        cmdRequestFriend.Enabled = false;
                    }
                    // sent, accepted or denied
                    else
                        cmdRequestFriend.Visible = false;

                    // is request sent from the owner to the surfer?
                    ret = Common.IsRequestSent(userId, cookieId);
                    // sent, waiting for response
                    if (ret == 1)
                    {
                        cmdRequestFriend.Visible = false;
                        cmdAccept.Visible = true;
                        cmdDeny.Visible = true;
                    }

                    GetPostList(userId, Common.Permission.Public);
                }
            }
            // query string not proper
            else
            {
                Response.Redirect("Profile.aspx?id=" + cookieId.ToString());
            }
        }
  
        protected int[] RandomFriendListRowIndexes(int count, int sum)
        {
            int[] rowIndexes = new int[sum];
            int i = 0;

            while (i < rowIndexes.Length)
            {
                rowIndexes[i] = i++;
            }

            Random ran = new Random();
            while (i > 1)
            {
                int j = ran.Next(i);
                int temp = rowIndexes[--i];
                rowIndexes[i] = rowIndexes[j];
                rowIndexes[j] = temp;
            }

            if (count < sum)
            {
                int[] rowIndexesToReturn = new int[count];
                for (i = 0; i < count; i++)
                    rowIndexesToReturn[i] = rowIndexes[i];
                return rowIndexesToReturn;
            }
            else
            {
                return rowIndexes;
            }

            //for (int i = 0; i < count; i++)
            //{
            //    rowIDs[i] = a.Next(0, sum);
            //    while (true)
            //    {
            //        bool dup = false;
            //        for (int j = 0; j < i; j++)
            //        {
            //            if (rowIDs[j] == rowIDs[i])
            //            {
            //                dup = true;
            //                break;
            //            }
            //        }
            //        if (dup == false)
            //            break;
            //        rowIDs[i] = a.Next(0, sum);
            //    }
            //}
            //return rowIDs;
        }

        protected void GetFriendList(int userId)
        {
            string selectSQL = "SELECT friend_id FROM [friend] WHERE user_id = @userId";
            SqlConnection conn = new SqlConnection(Common.connString);
            SqlCommand cmd = new SqlCommand(selectSQL, conn);
            cmd.Parameters.AddWithValue("@userId", userId);
            SqlDataAdapter adapter = new SqlDataAdapter(cmd);
            DataSet dsFriend = new DataSet();

            conn.Open();
            adapter.Fill(dsFriend, "friend");
            conn.Close();

            if (dsFriend.Tables["friend"].Rows.Count == 0)
                return;

            // randomize the order of the list to display
            int numberOfFriendToDisplay = dsFriend.Tables["friend"].Rows.Count;
            if (numberOfFriendToDisplay > 10)
                numberOfFriendToDisplay = 10;
            int[] rowIndexes = new int[numberOfFriendToDisplay];
            rowIndexes = RandomFriendListRowIndexes(numberOfFriendToDisplay, dsFriend.Tables["friend"].Rows.Count);

            DataRow row;
            for (int i = 0; i < rowIndexes.Length; i++)
            {
                try
                {
                    row = dsFriend.Tables["friend"].Rows[rowIndexes[i]];
                    FriendListItem friendItem = new FriendListItem();
                    friendItem = (FriendListItem)LoadControl("~/UserControls/FriendListItem.ascx");
                    friendItem.FriendId = (int)row["friend_id"];
                    pnlFriends.Controls.Add(friendItem);
                }
                catch (Exception profileE)
                {
                    Common.WriteToEventLog(profileE, "GetFriendList");
                }
            }

            //foreach (DataRow drow in dsFriend.Tables["friend"].Rows)
            //{
            //    FriendListItem friendItem = new FriendListItem();
            //    friendItem = (FriendListItem)LoadControl("~/FriendListItem.ascx");
            //    friendItem.FriendId = (int)drow["friend_id"];
            //    pnlFriends.Controls.Add(friendItem);
            //}
        }

        protected void GetPostList(int userId, Common.Permission permission)
        {
            // TODO: chia sẻ với nhóm
            string selectActivitySql = "";
            SqlConnection conn = new SqlConnection(Common.connString);
            SqlCommand cmd;
            SqlDataAdapter adapter;

            switch (permission)
            {
                case Common.Permission.Private:
                    {
                        string selectFriendSql = "SELECT * FROM [friend] WHERE user_id = @userId";
                        cmd = new SqlCommand(selectFriendSql, conn);
                        cmd.Parameters.AddWithValue("@userId", userId);
                        adapter = new SqlDataAdapter(cmd);
                        DataSet dsFriends = new DataSet();

                        conn.Open();
                        adapter.Fill(dsFriends, "friends");
                        conn.Close();

                        if (dsFriends.Tables["friends"].Rows.Count > 0)
                        {
                            selectActivitySql = "SELECT TOP (20) * FROM "
                                                + "("
                                                + "SELECT * FROM [activity] "
                                                + "WHERE user_id IN (";
                            foreach (DataRow row in dsFriends.Tables["friends"].Rows)
                            {
                                selectActivitySql = selectActivitySql + row["friend_id"].ToString() + ", ";
                            }
                            selectActivitySql += "0) AND "
                                                + "permission IN (1, 2) "
                                                + "AND song_up_id IS NULL "
                                                + "UNION "
                                                + "SELECT * FROM [activity] "
                                                + "WHERE user_id = @userId"
                                                + ") AS derivedtbl_1 "
                                                + "ORDER BY time DESC";
                        }
                        else
                            selectActivitySql = "SELECT TOP (20) * FROM [activity] "
                                                + "WHERE user_id = @userId ORDER BY time DESC";
                    }
                    break;
                case Common.Permission.Friend:
                    {
                        string selectFriendSql = "SELECT * FROM [friend] WHERE user_id = @userId";
                        cmd = new SqlCommand(selectFriendSql, conn);
                        cmd.Parameters.AddWithValue("@userId", userId);
                        adapter = new SqlDataAdapter(cmd);
                        DataSet dsFriends = new DataSet();

                        conn.Open();
                        adapter.Fill(dsFriends, "friends");
                        conn.Close();

                        if (dsFriends.Tables["friends"].Rows.Count > 0)
                        {
                            selectActivitySql = "SELECT TOP (20) * FROM "
                                                + "("
                                                + "SELECT * FROM [activity] "
                                                + "WHERE user_id IN (";
                            foreach (DataRow row in dsFriends.Tables["friends"].Rows)
                            {
                                selectActivitySql = selectActivitySql + row["friend_id"].ToString() + ", ";
                            }
                            selectActivitySql += "0) AND "
                                                + "permission = 2 "
                                                + "AND song_up_id IS NULL "
                                                + "UNION "
                                                + "SELECT * FROM [activity] "
                                                + "WHERE user_id = @userId "
                                                + "AND permission IN (1, 2) "
                                                + "AND song_up_id IS NULL "
                                                + ") AS derivedtbl_1 "
                                                + "ORDER BY time DESC";
                        }
                        else
                            selectActivitySql = "SELECT TOP (20) * FROM [activity] "
                                                + "WHERE user_id = @userId AND permission IN (1, 2) "
                                                + "AND song_up_id IS NULL "
                                                + "ORDER BY time DESC";
                    }
                    break;
                case Common.Permission.Public:
                    {
                        selectActivitySql = "SELECT TOP (20) * FROM [activity] "
                                                + "WHERE user_id = @userId AND permission = 2 "
                                                + "AND song_up_id IS NULL "
                                                + "ORDER BY time DESC";
                    }
                    break;
                default:
                    {
                        return; 
                    }
            }

            cmd = new SqlCommand(selectActivitySql, conn);
            cmd.Parameters.AddWithValue("@userId", userId);
            adapter = new SqlDataAdapter(cmd);
            DataSet dsActivities = new DataSet();

            conn.Open();
            adapter.Fill(dsActivities, "Activities");
            conn.Close();

            if (dsActivities.Tables["Activities"].Rows.Count == 0)
                return;

            foreach (DataRow row in dsActivities.Tables["Activities"].Rows)
            {
                try
                {
                    ActivityListItem activityItem = new ActivityListItem();
                    activityItem = (ActivityListItem)LoadControl("~/UserControls/ActivityListItem.ascx");
                    activityItem.ActivityId = (int)row["activity_id"];
                    pnlActivities.Controls.Add(activityItem);
                }
                catch (Exception profileE)
                {
                    Common.WriteToEventLog(profileE, "GetPostList");
                }
            }
        }

        public void cmdRequestFriend_Click(object sender, EventArgs e)
        {
            HttpCookie cookie = Request.Cookies["QTCookie"];
            string cookieId = cookie["ID"];
            string userId = Request.QueryString["id"];

            string insertSQL = "INSERT INTO [friendreq] VALUES (@idFrom, @idTo, @status)";
            SqlConnection conn = new SqlConnection(Common.connString);
            SqlCommand cmd = new SqlCommand(insertSQL, conn);

            cmd.Parameters.AddWithValue("@idFrom", cookieId);
            cmd.Parameters.AddWithValue("@idTo", userId);
            cmd.Parameters.AddWithValue("@status", "Sent");

            int added = 0;
            try
            {
                conn.Open();
                added = cmd.ExecuteNonQuery();
            }
            catch (Exception profileE)
            {
                conn.Close();
                Common.WriteToEventLog(profileE, "cmdRequestFriend_Click");
                Response.Redirect("Error.aspx");
            }

            conn.Close();
            if (added > 0)
            {
                cmdRequestFriend.Text = "Đã gửi đề nghị";
                cmdRequestFriend.Visible = true;
                cmdRequestFriend.Enabled = false;
                // TODO: chọn nhóm
            }
        }

        protected void GetRequestList(int userId)
        {
            string selectSql = "SELECT * FROM [friendreq] "
                                + "WHERE user_id = @userId "
                                + "AND friendreq_status = @status";
            SqlConnection conn = new SqlConnection(Common.connString);
            SqlCommand cmd = new SqlCommand(selectSql, conn);
            cmd.Parameters.AddWithValue("@userId", userId);
            cmd.Parameters.AddWithValue("@status", "Sent");

            SqlDataAdapter adapter = new SqlDataAdapter(cmd);
            DataSet dsRequest = new DataSet();

            conn.Open();
            adapter.Fill(dsRequest, "Requests");
            conn.Close();

            if (dsRequest.Tables["Requests"].Rows.Count == 0)
                return;

            foreach (DataRow row in dsRequest.Tables["Requests"].Rows)
            {
                try
                {
                    RequestListItem requestItem = new RequestListItem();
                    requestItem = (RequestListItem)LoadControl("~/UserControls/RequestListItem.ascx");
                    requestItem.FromId = (int)row["friendreq_from_id"];
                    requestItem.UserId = (int)row["user_id"];
                    pnlRequests.Controls.Add(requestItem);
                }
                catch (Exception profileE)
                {
                    Common.WriteToEventLog(profileE, "GetRequestList");
                }
            }
        }

        public void BtnUploadClicked(object sender, EventArgs e)
        {
            Response.Redirect("~/Websites/Upload.aspx");
        }
    }
}